﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TibcoQueueMonitor.Entities;
using TibcoQueueMonitor.TibcoAdminManagers;
using System.Collections.ObjectModel;

namespace TibcoQueueMonitor.Controls
{
    /// <summary>
    /// Interaction logic for Profile.xaml
    /// </summary>
    public partial class Profile : UserControl
    {
        #region Events
        /// <summary>
        /// Occurs when a status notification is available from the profile.
        /// </summary>
        public event EventHandler<StatusNotificationEventArgs> StatusNotification;

        /// <summary>
        /// Occurs when the profile selection has changed.
        /// </summary>
        public event EventHandler<EventArgs> ProfileSelectionChanged;

        /// <summary>
        /// Occurs when the profiles have been refreshed.
        /// </summary>
        public event EventHandler<EventArgs> ProfilesRefreshed;

        #endregion //Events

        #region Private Fields
        private ObservableCollection<EmsServerProfile> _emsServerProfiles;
        private Dictionary<string, ClientHost> _clientHosts;

        #endregion //Private Fields

        #region Public Properties

        /// <summary>
        /// Gets the hosts.
        /// </summary>
        /// <value>The client hosts.</value>
        public Dictionary<string, ClientHost> ClientHosts
        {
            get { return _clientHosts; }
        }

        /// <summary>
        /// Gets the EMS server profiles.
        /// </summary>
        /// <value>The EMS server profiles.</value>
        public ObservableCollection<EmsServerProfile> EmsServerProfiles
        {
            get { return _emsServerProfiles; }
        }

        public object SelectedItem
        {
            get { return this.cmbServerProfiles.SelectedItem; }
            set { this.cmbServerProfiles.SelectedItem = value; }
        }

        public int SelectedIndex
        {
            get { return this.cmbServerProfiles.SelectedIndex; }
            set { this.cmbServerProfiles.SelectedIndex = value; }
        }

        public string EmsHostname
        {
            get { return this.txtbEmsHostname.Text; }
            set { this.txtbEmsHostname.Text = value; }
        }

        public string EmsPort
        {
            get { return this.txtbEmsPort.Text; }
            set { this.txtbEmsPort.Text = value; }
        }

        public string UserName
        {
            get { return this.txtbUsername.Text; }
            set { this.txtbUsername.Text = value; }
        }

        public string Password
        {
            get { return this.pboxPassword.Password; }
            set { this.pboxPassword.Password = value; }
        }

        #endregion //Public Properties

        #region Constructors
        public Profile()
        {
            InitializeComponent();

            _emsServerProfiles = new ObservableCollection<EmsServerProfile>();
            _clientHosts = new Dictionary<string, ClientHost>();

            // Fill profiles dropdown
            this.cmbServerProfiles.ItemsSource = _emsServerProfiles;
        }

        #endregion //Constructors

        #region Public Methods
        /// <summary>
        /// Refreshes the profiles.
        /// </summary>
        public void RefreshProfiles()
        {
            Dictionary<string, EmsServerProfile> emsProfilesIndex = TibcoAdminConfigurationManager.GetEmsServerProfiles();
            _clientHosts = TibcoAdminConfigurationManager.GetHosts();
            if (_clientHosts == null)
            {
                TibcoAdminConfigurationManager.CreateHostsFile();
            }
            else if (_clientHosts.Count == 0)
            {
                TibcoAdminConfigurationManager.CreateHostsFile();
            }

            // Refresh profiles drop down
            _emsServerProfiles = new ObservableCollection<EmsServerProfile>(emsProfilesIndex.Values);
            cmbServerProfiles.ItemsSource = _emsServerProfiles;
            if (cmbServerProfiles.Items != null && cmbServerProfiles.Items.Count > 0)
            {
                cmbServerProfiles.SelectedIndex = 0;
                OnProfilesRefreshed();
            }
        }

        #endregion //Public Methods

        #region Protected Methods
        /// <summary>
        /// Called when a status notification occurs.
        /// </summary>
        /// <param name="statusMessage">The status message.</param>
        /// <param name="isError">if set to <c>true</c> [is error].</param>
        protected virtual void OnStatusNotification(string statusMessage, bool isError)
        {
            if (StatusNotification != null)
            {
                StatusNotification(this, new StatusNotificationEventArgs(statusMessage, isError));
            }
        }

        /// <summary>
        /// Called when profile selection has changed.
        /// </summary>
        protected virtual void OnProfileSelectionChanged()
        {
            if (ProfileSelectionChanged != null)
            {
                ProfileSelectionChanged(this, EventArgs.Empty);
            }
        }

        /// <summary>
        /// Called when the profiles are refreshed.
        /// </summary>
        protected virtual void OnProfilesRefreshed()
        {
            if (ProfilesRefreshed != null)
            {
                ProfilesRefreshed(this, EventArgs.Empty);
            }
        }

        #endregion //Protected Methods

        #region Private Methods
            #region Private Methods.Event Handlers
        private void btnSaveProfile_Click(object sender, RoutedEventArgs e)
        {
            //// Determine if the profile box has a value.
            if (String.IsNullOrWhiteSpace(cmbServerProfiles.Text))
            {
                OnStatusNotification("A name must be specified under the 'EMS Server Profile' in order to save this profile.", true);
                return;
            }

            //// Create new profile based on current settings
            EmsServerProfile newProfile = GetCurrentProfileValues();

            //// Determine if profile is new, or being updated
            if (_emsServerProfiles.Contains(newProfile))
            {
                // Profile exists. Update in-memory profile.
                EmsServerProfile existingProfile = _emsServerProfiles[_emsServerProfiles.IndexOf(newProfile)];
                existingProfile.Hostname = newProfile.Hostname;
                existingProfile.Password = newProfile.Password;
                existingProfile.Port = newProfile.Port;
                existingProfile.User = newProfile.User;
            }
            else
            {
                // Profile is new, add profile to collection
                _emsServerProfiles.Add(newProfile);
            }

            //// Persist to configuration file
            TibcoAdminConfigurationManager.SaveEmsServerProfiles(_emsServerProfiles);

            OnStatusNotification("Profile saved", false);

            // Perform 
            var a = from profile in _emsServerProfiles
                    where profile.ProfileDisplayName == newProfile.ProfileDisplayName
                    select profile;

            cmbServerProfiles.SelectedItem = a.FirstOrDefault();
        }

        private void btnDeleteProfile_Click(object sender, RoutedEventArgs e)
        {
            ShowConfirmation(true);
        }

        private void btnClearProfileFields_Click(object sender, RoutedEventArgs e)
        {
            ClearFields();
        }

        private void btnConfirm_Click(object sender, RoutedEventArgs e)
        {
            EmsServerProfile currentProfile = GetCurrentProfileValues();

            //// Determine if profile exists, or is temporary
            if (_emsServerProfiles.Contains(currentProfile))
            {
                // Profile exists. Remove from in-memory list.
                _emsServerProfiles.RemoveAt(_emsServerProfiles.IndexOf(currentProfile));

                //// Persist to configuration file
                TibcoAdminConfigurationManager.SaveEmsServerProfiles(_emsServerProfiles);
            }

            ClearFields();
            ShowConfirmation(false);
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            ShowConfirmation(false);
        }

        private void cmbServerProfiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cmbServerProfiles.SelectedItem != null)
            {
                if (!(cmbServerProfiles.SelectedItem is EmsServerProfile))
                {
                    OnStatusNotification("Serious error encountered in the application. Unable to evaluate profile.", true);
                    return;
                }

                EmsServerProfile profile = cmbServerProfiles.SelectedItem as EmsServerProfile;
                txtbEmsHostname.Text = profile.Hostname;
                txtbEmsPort.Text = profile.Port;
                txtbUsername.Text = profile.User;
                pboxPassword.Password = profile.Password;

                OnProfileSelectionChanged();
            }
        }

            #endregion //Private Methods.Event Handlers

        private EmsServerProfile GetCurrentProfileValues()
        {
            EmsServerProfile newProfile = new EmsServerProfile();

            if (!string.IsNullOrWhiteSpace(cmbServerProfiles.Text))
            {
                newProfile.ProfileName = cmbServerProfiles.Text.Trim();
            }
            newProfile.Hostname = txtbEmsHostname.Text;
            newProfile.Password = pboxPassword.Password;
            newProfile.Port = txtbEmsPort.Text;
            newProfile.User = txtbUsername.Text;

            return newProfile;
        }

        private void ClearFields()
        {
            cmbServerProfiles.Text = null;
            txtbEmsHostname.Text = null;
            txtbEmsPort.Text = null;
            txtbUsername.Text = null;
            pboxPassword.Password = null;
        }

        private void ShowConfirmation(bool showConfirm)
        {
            switch (showConfirm)
            {
                case true:
                    cmbServerProfiles.Focus();

                    btnSaveProfile.Visibility = System.Windows.Visibility.Hidden;
                    btnSaveProfile.IsTabStop = false;
                    btnClearProfileFields.Visibility = System.Windows.Visibility.Collapsed;
                    btnClearProfileFields.IsTabStop = false;
                    btnConfirm.Visibility = System.Windows.Visibility.Visible;
                    btnConfirm.IsTabStop = true;
                    btnCancel.Visibility = System.Windows.Visibility.Visible;
                    btnConfirm.IsTabStop = true;
                    btnDeleteProfile.Visibility = System.Windows.Visibility.Hidden;
                    btnDeleteProfile.IsTabStop = false;

                    btnConfirm.Focus();

                    cmbServerProfiles.IsEnabled = false;
                    txtbEmsHostname.IsEnabled = false;
                    txtbEmsPort.IsEnabled = false;
                    txtbUsername.IsEnabled = false;
                    pboxPassword.IsEnabled = false;

                    break;
                case false:
                    cmbServerProfiles.IsEnabled = true;
                    txtbEmsHostname.IsEnabled = true;
                    txtbEmsPort.IsEnabled = true;
                    txtbUsername.IsEnabled = true;
                    pboxPassword.IsEnabled = true;

                    cmbServerProfiles.Focus();

                    btnSaveProfile.Visibility = System.Windows.Visibility.Visible;
                    btnSaveProfile.IsTabStop = true;
                    btnClearProfileFields.Visibility = System.Windows.Visibility.Visible;
                    btnClearProfileFields.IsTabStop = true;
                    btnConfirm.Visibility = System.Windows.Visibility.Hidden;
                    btnConfirm.IsTabStop = false;
                    btnCancel.Visibility = System.Windows.Visibility.Hidden;
                    btnCancel.IsTabStop = false;
                    btnDeleteProfile.Visibility = System.Windows.Visibility.Visible;
                    btnDeleteProfile.IsTabStop = true;
                    break;
            }
        }

        #endregion //Private Methods

    }
}
